package com.fany.utils;

import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import com.fany.fastsearcher.R;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

public class FileHelper
{
    public static List<String> enumFiles(String path)
    {
        List<String> retFiles = new ArrayList<String>();
        try
        {
            File baseFile = new File(path);
            File[] childFiles = baseFile.listFiles();
            assert childFiles != null;
            for (File file : childFiles)
            {
                retFiles.add(file.getName());
            }
        }
        catch (Exception ignored)
        {

        }
        Comparator<String> comparator = new Comparator<String>()
        {
            @Override
            public int compare(String lhs, String rhs)
            {
                return lhs.compareTo(rhs);
            }
        };
        Collections.sort(retFiles, comparator);
        return retFiles;
    }

    private static final HashMap<String, String> FileTypes = new HashMap<String, String>();

    static
    {
        FileTypes.put("FFD8FF", "jpg");
        FileTypes.put("89504E47", "png");
        FileTypes.put("47494638", "gif");
        FileTypes.put("49492A00", "tif");
        FileTypes.put("424D", "bmp");
        FileTypes.put("41433130", "dwg");
        FileTypes.put("38425053", "psd");
        FileTypes.put("7B5C727466", "rtf");
        FileTypes.put("3C3F786D6C", "xml");
        FileTypes.put("68746D6C3E", "html");
        FileTypes.put("44656C69766572792D646174653A", "eml");
        FileTypes.put("D0CF11E0", "doc");
        FileTypes.put("5374616E64617264204A", "mdb");
        FileTypes.put("252150532D41646F6265", "ps");
        FileTypes.put("255044462D312E", "pdf");
        FileTypes.put("504B0304", "zip");
        FileTypes.put("52617221", "rar");
        FileTypes.put("57415645", "wav");
        FileTypes.put("41564920", "avi");
        FileTypes.put("2E524D46", "rm");
        FileTypes.put("000001BA", "mpg");
        FileTypes.put("000001B3", "mpg");
        FileTypes.put("6D6F6F76", "mov");
        FileTypes.put("3026B2758E66CF11", "asf");
        FileTypes.put("4D546864", "mid");
        FileTypes.put("1F8B08", "gz");
    }

    public static String getFileType(String filePath)
    {
        return FileTypes.get(getFileHeader(filePath));
    }

    private static String getFileHeader(String filePath)
    {
        FileInputStream is = null;
        String value = null;
        try
        {
            is = new FileInputStream(filePath);
            byte[] b = new byte[3];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
        }
        catch (Exception ignored)
        {
        }
        finally
        {
            if (null != is)
            {
                try
                {
                    is.close();
                }
                catch (IOException ignored)
                {
                }
            }
        }
        return value;
    }

    private static String bytesToHexString(byte[] src)
    {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0)
        {
            return null;
        }
        String hv;
        for (byte aSrc : src)
        {
            hv = Integer.toHexString(aSrc & 0xFF).toUpperCase(Locale.CHINA);
            if (hv.length() < 2)
            {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }

    public static String extractFileExtension(String fullpath)
    {
        if (fullpath == null)
        {
            return "";
        }
        int start = fullpath.lastIndexOf(".");
        if ((start != -1) && (fullpath.length() > start + 1))
        {
            return fullpath.substring(start);
        }
        else
        {
            return "";
        }
    }

    public static String extractFileName(String fullpath)
    {
        if (fullpath == null)
        {
            return "";
        }
        int start = fullpath.lastIndexOf("/");
        if ((start != -1) && (fullpath.length() > start + 1))
        {
            return fullpath.substring(start + 1);
        }
        else
        {
            return "";
        }
    }

    public static String extractDirectoryName(String fullpath)
    {
        if (fullpath == null)
        {
            return "";
        }
        int start = fullpath.lastIndexOf("/");
        if ((start != -1) && (fullpath.length() > start + 1))
        {
            if (start == 0)
            {
                return "/";
            }
            else
            {
                return fullpath.substring(0, start);
            }
        }
        else
        {
            return "";
        }
    }

    public static boolean isDirectory(String path)
    {
        File file = new File(path);
        return file.isDirectory();
    }

    public static Intent openFileIntent(String filename)
    {
        File file = new File(filename);
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        String type = MimeType.getMimeType(file);
        intent.setDataAndType(Uri.fromFile(file), type);
        return intent;
    }

    public static boolean deleteFile(String path)
    {
        File file = new File(path);
        try
        {
            if (!file.isFile() || !file.exists())
            {
                return false;
            }
            return file.delete();
        }
        catch (Exception e)
        {
            return false;
        }
    }

    public static boolean deleteDirectory(String path)
    {
        File file = new File(path);
        if (file.isFile())
        {
            file.delete();
            return true;
        }
        if (file.isDirectory())
        {
            File[] childFiles = file.listFiles();
            if ((childFiles != null) && (childFiles.length > 0))
            {
                for (int i = 0; i < childFiles.length; i++)
                {
                    deleteDirectory(childFiles[i].getAbsolutePath());
                }
            }
            file.delete();
        }
        return false;
    }

    public static boolean renameFile(String path, String newName, StringBuffer newPath)
    {
        File file = new File(path);
        try
        {
            if (!file.isFile() || !file.exists())
            {
                return false;
            }
            newPath.append(extractDirectoryName(path) + File.separator + newName);
            return file.renameTo(new File(newPath.toString()));
        }
        catch (Exception e)
        {
            return false;
        }
    }

    public static boolean containsContent(String filename, String content)
    {
        File file = new File(filename);
        try
        {
            if (!file.isFile() || !file.exists())
            {
                return false;
            }
            // return file.renameTo(new File(extractDirectoryName(path) +
            // File.separator + newName));
            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }

    public static FileKind getFileKindByExtension(String extension)
    {
        ArrayList<FileTypeInfo> infos = getFileTypeInfos();
        for (FileTypeInfo info : infos)
        {
            if (info.extension.equals(extension))
            {
                return info.kind;
            }
        }
        return FileKind.Unknown;
    }

    public enum FileKind
    {
        Unknown, Picture, Music, Video, Document, Application, Compressed, Configure
    }

    private static class FileTypeInfo
    {
        public FileTypeInfo(int uniqueId, String extension, FileKind kind, int resourceId)
        {
            this.uniqueId = uniqueId;
            this.extension = extension;
            this.kind = kind;
            this.resourceId = resourceId;
        }

        public int uniqueId;
        public String extension;
        public FileKind kind;
        public int resourceId;
    }

    private static ArrayList<FileTypeInfo> _fileTypeInfos;

    private static ArrayList<FileTypeInfo> getFileTypeInfos()
    {
        if (_fileTypeInfos == null)
        {
            _fileTypeInfos = new ArrayList<FileTypeInfo>();
            _fileTypeInfos.add(new FileTypeInfo(100, ".apk", FileKind.Application, R.drawable.filetype_apk));

            _fileTypeInfos.add(new FileTypeInfo(200, ".gz", FileKind.Compressed, R.drawable.filetype_gz));
            _fileTypeInfos.add(new FileTypeInfo(201, ".iso", FileKind.Compressed, R.drawable.filetype_iso));
            _fileTypeInfos.add(new FileTypeInfo(202, ".jar", FileKind.Compressed, R.drawable.filetype_jar));
            _fileTypeInfos.add(new FileTypeInfo(203, ".rar", FileKind.Compressed, R.drawable.filetype_rar));
            _fileTypeInfos.add(new FileTypeInfo(204, ".taz", FileKind.Compressed, R.drawable.filetype_taz));
            _fileTypeInfos.add(new FileTypeInfo(205, ".zip", FileKind.Compressed, R.drawable.filetype_zip));

            _fileTypeInfos.add(new FileTypeInfo(300, ".cfg", FileKind.Configure, R.drawable.filetype_cfg));
            _fileTypeInfos.add(new FileTypeInfo(301, ".ini", FileKind.Configure, R.drawable.filetype_ini));
            _fileTypeInfos.add(new FileTypeInfo(302, ".db", FileKind.Configure, R.drawable.filetype_db));
            _fileTypeInfos.add(new FileTypeInfo(303, ".dat", FileKind.Configure, R.drawable.filetype_dat));
            _fileTypeInfos.add(new FileTypeInfo(304, ".conf", FileKind.Configure, R.drawable.filetype_conf));
            _fileTypeInfos.add(new FileTypeInfo(305, ".tmp", FileKind.Configure, R.drawable.filetype_tmp));
            _fileTypeInfos.add(new FileTypeInfo(306, ".xml", FileKind.Configure, R.drawable.filetype_xml));


            _fileTypeInfos.add(new FileTypeInfo(400, ".chm", FileKind.Document, R.drawable.filetype_chm));
            _fileTypeInfos.add(new FileTypeInfo(401, ".csv", FileKind.Document, R.drawable.filetype_csv));
            _fileTypeInfos.add(new FileTypeInfo(402, ".doc", FileKind.Document, R.drawable.filetype_doc));
            _fileTypeInfos.add(new FileTypeInfo(404, ".pdf", FileKind.Document, R.drawable.filetype_pdf));
            _fileTypeInfos.add(new FileTypeInfo(405, ".ppt", FileKind.Document, R.drawable.filetype_ppt));
            _fileTypeInfos.add(new FileTypeInfo(406, ".rtf", FileKind.Document, R.drawable.filetype_rtf));
            _fileTypeInfos.add(new FileTypeInfo(407, ".txt", FileKind.Document, R.drawable.filetype_txt));
            _fileTypeInfos.add(new FileTypeInfo(408, ".xls", FileKind.Document, R.drawable.filetype_xls));

            _fileTypeInfos.add(new FileTypeInfo(500, ".ape", FileKind.Music, R.drawable.filetype_ape));
            _fileTypeInfos.add(new FileTypeInfo(501, ".asf", FileKind.Music, R.drawable.filetype_asf));
            _fileTypeInfos.add(new FileTypeInfo(502, ".mid", FileKind.Music, R.drawable.filetype_mid));
            _fileTypeInfos.add(new FileTypeInfo(503, ".mp3", FileKind.Music, R.drawable.filetype_mp3));
            _fileTypeInfos.add(new FileTypeInfo(504, ".ogg", FileKind.Music, R.drawable.filetype_ogg));
            _fileTypeInfos.add(new FileTypeInfo(505, ".wav", FileKind.Music, R.drawable.filetype_wav));

            _fileTypeInfos.add(new FileTypeInfo(600, ".bmp", FileKind.Picture, R.drawable.filetype_bmp));
            _fileTypeInfos.add(new FileTypeInfo(601, ".gif", FileKind.Picture, R.drawable.filetype_gif));
            _fileTypeInfos.add(new FileTypeInfo(602, ".ico", FileKind.Picture, R.drawable.filetype_ico));
            _fileTypeInfos.add(new FileTypeInfo(603, ".jpg", FileKind.Picture, R.drawable.filetype_jpg));
            _fileTypeInfos.add(new FileTypeInfo(604, ".jpeg", FileKind.Picture, R.drawable.filetype_jpeg));
            _fileTypeInfos.add(new FileTypeInfo(605, ".png", FileKind.Picture, R.drawable.filetype_png));
            _fileTypeInfos.add(new FileTypeInfo(606, ".tga", FileKind.Picture, R.drawable.filetype_tga));
            _fileTypeInfos.add(new FileTypeInfo(607, ".tif", FileKind.Picture, R.drawable.filetype_tif));
            _fileTypeInfos.add(new FileTypeInfo(608, ".tiff", FileKind.Picture, R.drawable.filetype_tiff));

            _fileTypeInfos.add(new FileTypeInfo(700, ".3gp", FileKind.Video, R.drawable.filetype_3gp));
            _fileTypeInfos.add(new FileTypeInfo(701, ".avi", FileKind.Video, R.drawable.filetype_avi));
            _fileTypeInfos.add(new FileTypeInfo(702, ".mp4", FileKind.Video, R.drawable.filetype_mp4));
            _fileTypeInfos.add(new FileTypeInfo(703, ".mpeg", FileKind.Video, R.drawable.filetype_mpeg));
            _fileTypeInfos.add(new FileTypeInfo(704, ".mpg", FileKind.Video, R.drawable.filetype_mpg));
            _fileTypeInfos.add(new FileTypeInfo(705, ".rm", FileKind.Video, R.drawable.filetype_rm));
            _fileTypeInfos.add(new FileTypeInfo(707, ".swf", FileKind.Video, R.drawable.filetype_swf));
            _fileTypeInfos.add(new FileTypeInfo(708, ".wmv", FileKind.Video, R.drawable.filetype_wmv));
        }
        return _fileTypeInfos;
    }

    public static List<String> getExtensionsByFileKind(FileKind kind)
    {
        ArrayList<String> result = new ArrayList<String>();
        ArrayList<FileTypeInfo> infos = getFileTypeInfos();
        for (FileTypeInfo info : infos)
        {
            if (info.kind.equals(kind))
            {
                result.add(info.extension);
            }
        }
        return result;
    }

    public static int getResourceIdByFileExtension(String extension)
    {
        ArrayList<FileTypeInfo> infos = getFileTypeInfos();
        for (FileTypeInfo info : infos)
        {
            if (info.extension.equals(extension))
            {
                return info.resourceId;
            }
        }
        return 0;
    }

    public static int getUniqueIdByFileExtension(String extension)
    {
        ArrayList<FileTypeInfo> infos = getFileTypeInfos();
        for (FileTypeInfo info : infos)
        {
            if (info.extension.equals(extension))
            {
                return info.uniqueId;
            }
        }
        return 0;
    }

    public static String getTypeByFileExtension(String extension)
    {
        ArrayList<FileTypeInfo> infos = getFileTypeInfos();
        for (FileTypeInfo info : infos)
        {
            if (info.extension.equals(extension))
            {
                switch (info.kind)
                {
                    case Application:
                        return "Android安装包";
                    case Configure:
                        return "配置文件";
                    case Compressed:
                        return "压缩文件";
                    case Document:
                        return "文档";
                    case Music:
                        return "音频文件";
                    case Picture:
                        return "图片";
                    case Video:
                        return "视频文件";
                    default:
                        return "Unknown";
                }
            }
        }
        return "Unknown";
    }

    public static String getStoragePath()
    {
        String dbDir = Environment.getExternalStorageDirectory().getAbsolutePath();
        dbDir += File.separator + "searching";
        File dirFile = new File(dbDir);
        if (!dirFile.exists())
        {
            dirFile.mkdirs();
        }
        return dbDir;
    }

    public static File getSubStoragePath(String subPath)
    {
        String dbDir = getStoragePath();
        String path = FileHelper.getStoragePath() + File.separator + subPath;
        File result = new File(path);
        if (!result.exists())
        {
            result.mkdirs();
        }
        return result;
    }

    public static String combineFileName(String path, String name)
    {
        if (path.endsWith(File.separator))
        {
            return File.separator + name;
        }
        else
        {
            return path + File.separator + name;
        }
    }
}
